package br.edu.unifei.cct720.trabalho04.utils;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

import br.edu.unifei.cct720.trabalho04.utils.formas.Arco;
import br.edu.unifei.cct720.trabalho04.utils.formas.Reta;
import br.edu.unifei.cct720.trabalho04.utils.ponto.Ponto;
import br.edu.unifei.cct720.trabalho04.utils.ponto.Pontos;

/**
 * Classe responsavel por representar a forma
 * geometrica da area de trabalho
 * 
 * @author fknappe
 *
 */
public class AreaDeTrabalho {
	
	// Declaracao de variaveis de instacia
	private int altura = 0;
	private int largura = 0;
	private Ponto referencia = null;
	private ArrayList<Arco> arcosSuperiores = null;
	private ArrayList<Arco> arcosInferiores = null;
	
	/**
	 * Construtor 
	 * 
	 * @param largura
	 * @param altura
	 * @param referencia
	 */
	public AreaDeTrabalho (int largura, int altura,Ponto referencia) {
		this.altura = altura;
		this.largura = largura;
		this.referencia = referencia;
	}
	
	
	/**
	 * Metodo responsavel por plotar a area de
	 * trabalho
	 * 
	 * @param Graphics g
	 */
	public void desenha (Graphics g) {
		Pontos pontos = new Pontos();
		pontos.addAll(this.getPontos());
		
		for (Ponto ponto : pontos) {
			ponto.plota(g);
		}		
	}
	
	/**
	 * Metodo responsavel por verificar se um ponto esta
	 * dentro da area de trabalho
	 * 
	 * @param Ponto p
	 * @return boolean
	 */
	public boolean dentro (Ponto p) {
		if (p.getX()>this.largura) return false;
		if (p.getY()>this.altura) return false;
		
		for (Arco arco : arcosSuperiores) {
			int x = p.getX() - arco.getCentro().getX();
			int y = p.getY() - arco.getCentro().getY();
			
			if ( (x*x)+(y*y)>(arco.getRaio()*arco.getRaio()) ) return false;
			
		}
		return true;
	}
	
	/**
	 * Metodo responsavel por verificar se um ponto coincide
	 * com os pontos da area de trabalho
	 * 
	 * @param Ponto p
	 * @return boolean
	 */
	public boolean coincide (Ponto p) {
		for (Ponto ponto : getPontos()) {
			if (p.equals(ponto)) return true;
		}
		return false;
	}
	
	//Metodos getters e setters
	public void setArcosSuperiores (ArrayList<Arco> arcos) {
		this.arcosSuperiores = arcos;
	}
	
	public void setArcosInferiores (ArrayList<Arco> arcos) {
		this.arcosInferiores = arcos;
	}
	
	public ArrayList<Arco> getArcosSuperiores() {
		return arcosSuperiores;
	}

	public ArrayList<Arco> getArcosInferiores() {
		return arcosInferiores;
	}

	public int getAltura() {
		return altura;
	}

	public void setAltura(int altura) {
		this.altura = altura;
	}

	public int getLargura() {
		return largura;
	}

	public void setLargura(int largura) {
		this.largura = largura;
	}

	public Pontos getPontos () {
		 
		Pontos  pontos = new Pontos();

		// Desenhando os arcos Superiores	
		for (Arco arco : arcosSuperiores) {
			pontos.addAll(arco.getPontos());
		}
		// Ligando os arcos com retas
		Ponto pontoFinal = new Ponto(largura/2,0);	
		for (int i=0;i<arcosSuperiores.size();i++) {
			Ponto pontoInicial = new Ponto ((int)(Math.cos(arcosSuperiores.get(i).getAnguloInicial())*arcosSuperiores.get(i).getRaio()),
											 (int)(Math.sin(arcosSuperiores.get(i).getAnguloInicial())*arcosSuperiores.get(i).getRaio())  );
			pontoInicial.setY( pontoInicial.getY()*(-1) + arcosSuperiores.get(i).getCentro().getY()); 
			pontoInicial.setX( pontoInicial.getX() + arcosSuperiores.get(i).getCentro().getX());
			
			
			pontos.addAll(new Reta( pontoInicial, pontoFinal ).getPontos());
			
			
			
			pontoFinal = new Ponto (  (int)(Math.cos(arcosSuperiores.get(i).getAnguloFinal())*arcosSuperiores.get(i).getRaio()),
									(int)(Math.sin(arcosSuperiores.get(i).getAnguloFinal())*arcosSuperiores.get(i).getRaio())  );
			pontoFinal.setY( pontoFinal.getY()*(-1) + arcosSuperiores.get(i).getCentro().getY() ); 
			pontoFinal.setX( pontoFinal.getX() + arcosSuperiores.get(i).getCentro().getX() );
			
			
		}
		pontos.addAll(new Reta( pontoFinal, new Ponto(0,altura/2) ).getPontos());
		
//		 Desenhando os arcos Inferiores
		for (Arco arco : arcosInferiores) {
			pontos.addAll(arco.getPontos());
		}
		// Ligando os arcos com retas
		pontoFinal = new Ponto(0,altura/2);	
		for (int i=0;i<arcosInferiores.size();i++) {
			Ponto pontoInicial = new Ponto ((int)(Math.cos(arcosInferiores.get(i).getAnguloInicial())*arcosInferiores.get(i).getRaio()),
											 (int)(Math.sin(arcosInferiores.get(i).getAnguloInicial())*arcosInferiores.get(i).getRaio())  );
			pontoInicial.setY( pontoInicial.getY()*(-1) + arcosInferiores.get(i).getCentro().getY()); 
			pontoInicial.setX( pontoInicial.getX() + arcosInferiores.get(i).getCentro().getX());
			
			
			pontos.addAll(new Reta( pontoInicial, pontoFinal ).getPontos());
			
			
			
			pontoFinal = new Ponto (  (int)(Math.cos(arcosInferiores.get(i).getAnguloFinal())*arcosInferiores.get(i).getRaio()),
									(int)(Math.sin(arcosInferiores.get(i).getAnguloFinal())*arcosInferiores.get(i).getRaio())  );
			pontoFinal.setY( pontoFinal.getY()*(-1) + arcosInferiores.get(i).getCentro().getY() ); 
			pontoFinal.setX( pontoFinal.getX() + arcosInferiores.get(i).getCentro().getX() );
			
			
		}
		pontos.addAll(new Reta( pontoFinal, new Ponto(largura/2,altura) ).getPontos());
		
		
		// Espelhamento em X
		Pontos pontosEspelhados = new Pontos () ;
		for (Ponto p : pontos) {
			pontosEspelhados.add (new Ponto(largura - p.getX(), p.getY()));
		}
		pontos.addAll(pontosEspelhados);		
		return pontos;
		
	}
}

